package com.raidan.dclog.face.console;

import java.sql.Connection;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.PosixParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.raidan.dclog.core.Config;
import com.raidan.dclog.core.Database;
import com.raidan.dclog.core.Secundomer;
import com.raidan.dclog.core.Utils;
import com.raidan.dclog.core.parser.ParserCore;
import com.raidan.dclog.core.render.RenderCore;
import com.raidan.dclog.face.IVisual;

/**
 * Console interface. It will be replaced by windowed interface later.
 * 
 * @author raidan
 */
public class Console implements IVisual {

	private final static Logger logger = LoggerFactory.getLogger(Console.class);

	/**
	 * Main method -- flow of word.
	 * 
	 * @param args
	 * @throws Exception
	 */
	public void run(String args[]) throws Exception {
		
		// Using Apache goods
		Options options = new Options();
		options.addOption("keepLoaded", false, "Keep database loaded if already loaded at last time");
		options.addOption("skipRender", false, "Only load database and do not render result");

		CommandLineParser parser = new PosixParser();
		CommandLine cmd = parser.parse(options, args);

		Config.getInstance().setIProgressInstance(this);
		System.out.println(Utils.getVersion());
		/*
		 * ,Version . BUILD_NUMBER , new Date ( Version . BUILD_TIME )
		 */

		boolean keepAlreadyLoaded = false;

		boolean skipRender = false;

		// Let's check
		if (cmd.hasOption("keepLoaded")) {
			keepAlreadyLoaded = true;
			logger.debug("Using 'keepLoaded' mode -- no force database reload.");
		}

		// Again
		if (cmd.hasOption("skipRender")) {
			skipRender = true;
			logger.debug("Using 'skipRender' mode -- skip building reports.");
		}

		try {

			Secundomer common = new Secundomer();
			common.start();

			logger.debug("Start work flow.");

			Connection connection = Database.getInstance().getConnection();

			// If DB is OK (successfully loaded at last time) and 'keepLoaded'
			// flag is on -- skip loading logs.
			if (!keepAlreadyLoaded || !Database.getInstance().isDatabaseExists()) {
				logger.info("Loading logs into database.");
				new ParserCore().parse(connection);
			} else {
				logger.info("Using already loaded logs...");
			}

			// If 'skipRender' flag is on -- do not actually render result.
			if (skipRender) {
				logger.info("Skipping processing statistics.");
			} else {
				logger.info("Done. Processing statistics...");
				new RenderCore().render(connection);
			}

			common.stop();
			logger.info("ALL DONE at " + (float) common.getTotalTime() / 1000 + " sec");

		} finally {
			Database.getInstance().closeConnection();
		}
	}

	private boolean showbar = false;
	private int lastPercent = 0;

	public void processStart(boolean parallelMessaging) {
		showbar = !parallelMessaging;

		// Main idea -- do not show progress in console mode, when something
		// typing in parallel
		if (!showbar) {
			return; //
		}

		lastPercent = 0;
		System.out.print("Progress (1-40):");
	}

	public void process(int current, int total) {
		if (!showbar) {
			return; //
		}
		int percent = (int) Math.round(((double) current / (double) total) * 40.0d);
		if (percent > lastPercent) {
			for (int i = 0; i < percent - lastPercent; i++) {
				System.out.print("*");
			}
			lastPercent = percent;
		}

	}

	public void processOver() {
		if (!showbar) {
			return; //
		}

		this.process(1000, 1000);
		System.out.println("");

	}

	/**
	 * Main entrance
	 * 
	 * @param args
	 * @throws Exception
	 */
	public static void main(String args[]) throws Exception {
		new Console().run(args);
	}

}
